package com.swang.framework.core.base;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.swang.framework.core.util.ResultMapUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.*;

/**
 * @Description: 用于组装返回JSON的结果集
 * @ClassName: ResultObject.java
 * @Package: com.yuntai.med.core.base
 * @Author: wangxiaoning@hsyuntai.com
 * @Date: 2016年1月18日 下午5:09:04
 * @Copyright: 版权归 恒生芸泰网络 所有
 */

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
public class ResultObject implements Serializable {
	private static final long serialVersionUID = 6747666208905433497L;

	public static final String SUCCESS = "0";
	/** data 中类型为普通 Map&lt;String,Object>对象 */
	public static final int DATA_TYPE_MAP = 0;
	/** <p>data 中类型为普通 集合列表对象 List&lt;Map&lt;String,Object>> </p> */
	public static final int DATA_TYPE_LIST = 1;
	/** data 中类型为普通 javabean 单个对象 */
	public static final int DATA_TYPE_OBJECT = 2;
	

	private String errorNo = "0";
	private int dataType = 0;
	private String errorInfo = "";
	private Object data;

	public static final ResultObject  create(Object data) {
		return new ResultObject("0", "", 0, data);
	}
	
	public static final ResultObject  createListData(Object data) {
		return new ResultObject("0", "", 1, data);
	}
	
	public static final ResultObject  createFail(String errorNo, String errorInfo) {
		return new ResultObject(errorNo, errorInfo, 0, null);
	}
	
	public static final ResultObject  createFailList(String errorNo, String errorInfo) {
		return new ResultObject(errorNo, errorInfo, 1, null);
	}
	
	public static final ResultObject create(String errorNo, String errorInfo,  int dataType, Object data) {
		return new ResultObject(errorNo, errorInfo, dataType, data);
	}
	
	private ResultObject(String errorNo, String errorInfo,  int dataType, Object data) {
		this.errorNo = errorNo;
		this.dataType = dataType;
		this.errorInfo = errorInfo;
		this.data = data;
	}

	public static final ResultObject  createForMap(Map<String, Object> resMap) {
		if(ResultMapUtil.isSuccess(resMap)) {
			return new ResultObject("0", "", 0, resMap);
		} else {
			return new ResultObject(ResultMapUtil.getErrorNo(resMap), ResultMapUtil.getErrorInfo(resMap), 0, null);
		}
	}

	public boolean isSuccess() {
		return (SUCCESS == errorNo);
	}
	public boolean isFail() {
		return (!isSuccess());
	}
	
	public boolean isListData() {
		return (DATA_TYPE_LIST == dataType);
	}
	
	public boolean isEmptyData() {
		if (null == data) {
			return true;
		} else {
			if (data instanceof Collection) {
				return ((Collection<?>) data).isEmpty();
			} else if (data instanceof Map) {
				return ((Map<?, ?>) data).isEmpty();
			} else if (data.getClass().isArray()) {
				return 0 == Array.getLength(data);
			} else if (data instanceof Iterator) {
				return !((Iterator<?>) data).hasNext();
			} else if (data instanceof Enumeration) {
				return !((Enumeration<?>) data).hasMoreElements();
			}
			return false;
		}
	}
	
	public String getErrorNo() {
		return errorNo;
	}

	public void setErrorNo(String errorNo) {
		this.errorNo = errorNo;
	}

	public int getDataType() {
		return dataType;
	}

	public void setDataType(int dataType) {
		this.dataType = dataType;
	}

	public String getErrorInfo() {
		return errorInfo;
	}

	public void setErrorInfo(String errorInfo) {
		this.errorInfo = errorInfo;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}
	@Override
	public String toString() {
		 return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); 
	} 
	/**
	private String kind;
    private boolean result;
    private String msg;
    private Object data;
	 */
	public Map<String, Object> result() {
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("result", (StringUtils.equalsIgnoreCase(errorNo, SUCCESS)));
		result.put("msg", errorInfo);
		result.put("kind", String.valueOf(errorNo));
		result.put("data", data);
		return result;
	}
}
